﻿
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SerialAssistant
{
    class ComLib
    {

        //region java基本类型与byte字节数组的转换（包含大端，小端）

        //region  -------------- 32位   ----------------------

        /**
         * byte数组到int的转换(小端) LSB
         *
         * @param bytes
         * @return
         */
        public static int bToInt32lsb(byte[] bytes)
        {
            int int1 = bytes[0] & 0xff;
            int int2 = (bytes[1] & 0xff) << 8;
            int int3 = (bytes[2] & 0xff) << 16;
            int int4 = (bytes[3] & 0xff) << 24;
            return int1 | int2 | int3 | int4;
        }

        /**
         * byte数组到int的转换(大端) MSB
         *
         * @param bytes
         * @return
         */
        public static int bToInt32msb(byte[] bytes)
        {
            int int1 = bytes[3] & 0xff;
            int int2 = (bytes[2] & 0xff) << 8;
            int int3 = (bytes[1] & 0xff) << 16;
            int int4 = (bytes[0] & 0xff) << 24;

            return int1 | int2 | int3 | int4;
        }

        /**
         * 获取 32位以下 无符号 整数 （大端）
         *
         * @param byteBuf
         * @param readerIndex 开始位置
         * @param length      长度 4以下
         * @return
         */
        public static int bToU32msb(byte[] byteBuf, int readerIndex, int length)
        {
            int temp;
            temp = byteBuf[readerIndex] & 0x00ff;
            if (length > 1)
            {
                for (int i = 1; i < length; i++)
                {
                    temp = (temp << 8 | (byteBuf[readerIndex + i] & 0x00ff));
                }
            }
            return temp;
        }

        /**
         * 获取 32位以下 无符号 整数 （小端）
         *
         * @param byteBuf
         * @param readerIndex 开始位置
         * @param length      长度 4以下
         * @return
         */
        public static int bToU32lsb(byte[] byteBuf, int readerIndex, int length)
        {
            int temp;
            temp = byteBuf[readerIndex + length - 1] & 0x00ff;
            if (length > 1)
            {
                for (int i = length - 2; i >= 0; i--)
                {
                    temp = (temp << 8 | (byteBuf[readerIndex + i] & 0x00ff));
                }
            }
            return temp;
        }

        /**
         * 获取 32位以下 有符号 整数 （大端）
         *
         * @param byteBuf
         * @param readerIndex 开始位置
         * @param length      长度 4以下
         * @return
         */
        public static int bToInt32msb(byte[] byteBuf, int readerIndex, int length)
        {
            int temp;
            temp = byteBuf[readerIndex];
            if (length > 1)
            {
                for (int i = 1; i < length; i++)
                {
                    temp = (temp << 8);
                    temp = (temp | (byteBuf[readerIndex + i] & 0x00ff));
                }
            }
            return temp;
        }

        /**
         * 获取 32位以下 有符号 整数 （小端）
         *
         * @param byteBuf
         * @param readerIndex 开始位置
         * @param length      长度 4以下
         * @return
         */
        public static int bToInt32lsb(byte[] byteBuf, int readerIndex, int length)
        {
            int temp;
            temp = byteBuf[readerIndex + length - 1];
            if (length > 1)
            {
                for (int i = length - 2; i >= 0; i--)
                {
                    temp = (temp << 8 | (byteBuf[readerIndex + i] & 0x00ff));
                }
            }
            return temp;
        }

        /**
         * 将int转为高字节在前，低字节在后的byte数组（大端）
         *
         * @param n int
         * @return byte[]
         */
        public static byte[] int32ToBmsb(int n)
        {
            byte[] b = new byte[4];
            b[3] = (byte)(n & 0xff);
            b[2] = (byte)(n >> 8 & 0xff);
            b[1] = (byte)(n >> 16 & 0xff);
            b[0] = (byte)(n >> 24 & 0xff);
            return b;
        }

        /**
         * 将int转为高字节在前，低字节在后的byte数组（大端）
         *
         * @param buf
         * @param value      值
         * @param writeIndex 开始位置
         */
        public static void int32ToBmsb(byte[] buf, int value, int writeIndex)
        {
            buf[writeIndex + 0] = (byte)((value >> 24) & 0x00ff);
            buf[writeIndex + 1] = (byte)((value >> 16) & 0x00ff);
            buf[writeIndex + 2] = (byte)((value >> 8) & 0x00ff);
            buf[writeIndex + 3] = (byte)((value) & 0x00ff);
        }

        /**
         * 将int转为高字节在前，低字节在后的byte数组（大端）
         *
         * @param buf
         * @param value      值
         * @param writeIndex 开始位置
         * @param length     长度 8以下
         */
        public static void intToBmsb(byte[] buf, long value, int writeIndex, int length)
        {
            for (int i = 0; i < length; i++)
            {
                buf[writeIndex + i] = (byte)((value >> ((length - 1 - i) * 8)) & 0x00ff);
            }
        }


        /**
         * 将int转为低字节在前，高字节在后的byte数组（小端）
         *
         * @param n int
         * @return byte[]
         */
        public static byte[] int32ToBlsb(int n)
        {
            byte[] b = new byte[4];
            b[0] = (byte)(n & 0xff);
            b[1] = (byte)(n >> 8 & 0xff);
            b[2] = (byte)(n >> 16 & 0xff);
            b[3] = (byte)(n >> 24 & 0xff);
            return b;
        }

        /**
         * 将int转为高字节在前，低字节在后的byte数组（小端）
         *
         * @param buf
         * @param value      值
         * @param writeIndex 开始位置
         */
        public static void int32ToBlsb(byte[] buf, int value, int writeIndex)
        {
            buf[writeIndex + 0] = (byte)((value) & 0x00ff);
            buf[writeIndex + 1] = (byte)((value >> 8) & 0x00ff);
            buf[writeIndex + 2] = (byte)((value >> 16) & 0x00ff);
            buf[writeIndex + 3] = (byte)((value >> 24) & 0x00ff);
        }

        /**
         * 将int转为高字节在前，低字节在后的byte数组（小端）
         *
         * @param buf
         * @param value      值
         * @param writeIndex 开始位置
         * @param length     长度 8以下
         */
        public static void intToBlsb(byte[] buf, long value, int writeIndex, int length)
        {
            for (int i = 0; i < length; i++)
            {
                buf[writeIndex + i] = (byte)((value >> (i * 8)) & 0x00ff);
            }
        }

        //endregion

        //region  -=--------------16位----------------------------------


        /**
         * 将short转为高字节在前，低字节在后的byte数组（大端）
         *
         * @param n short
         * @return byte[]
         */
        public static byte[] shortToBmsb(short n)
        {
            byte[] b = new byte[2];
            b[1] = (byte)(n & 0xff);
            b[0] = (byte)(n >> 8 & 0xff);
            return b;
        }

        /**
         * 将short转为高字节在前，低字节在后的byte数组（大端）
         *
         * @param buf
         * @param value
         * @param writeIndex
         */
        public static void shortToBmsb(byte[] buf, short value, int writeIndex)
        {
            buf[writeIndex + 1] = (byte)(value & 0xff);
            buf[writeIndex + 0] = (byte)(value >> 8 & 0xff);
        }


        /**
         * 将short转为低字节在前，高字节在后的byte数组(小端)
         *
         * @param n short
         * @return byte[]
         */
        public static byte[] shortToBlsb(short n)
        {
            byte[] b = new byte[2];
            b[0] = (byte)(n & 0xff);
            b[1] = (byte)(n >> 8 & 0xff);
            return b;
        }

        /**
         * 将short转为低字节在前，高字节在后的byte数组(小端)
         *
         * @param buf
         * @param value
         * @param writeIndex
         */
        public static void shortToBlsb(byte[] buf, short value, int writeIndex)
        {
            buf[writeIndex + 0] = (byte)(value & 0xff);
            buf[writeIndex + 1] = (byte)(value >> 8 & 0xff);
        }

        /**
         * 读取小端byte数组为short
         *
         * @param b
         * @return
         */
        public static short bToShort_lsb(byte[] b)
        {
            return (short)(((b[1] << 8) | b[0] & 0xff));
        }

        /**
         * 读取小端byte数组为short
         *
         * @param byteBuf
         * @param readerIndex
         * @return
         */
        public static short bToShort_lsb(byte[] byteBuf, int readerIndex)
        {
            return (short)bToInt32lsb(byteBuf, readerIndex, 2);
        }

        /**
         * 读取大端byte数组为short
         *
         * @param b
         * @return
         */
        public static short bToShort_msb(byte[] b)
        {
            return (short)(((b[0] << 8) | b[1] & 0xff));
        }

        /**
         * 读取大端byte数组为short
         *
         * @param byteBuf
         * @param readerIndex
         * @return
         */
        public static short bToShort_msb(byte[] byteBuf, int readerIndex)
        {
            return (short)bToInt32msb(byteBuf, readerIndex, 2);
        }

        //endregion

        //region-------------------- 64 位---------------------------

        /**
         * long类型转byte[] (大端)
         *
         * @param n
         * @return
         */
        public static byte[] longToB_msb(long n)
        {
            byte[] b = new byte[8];
            b[7] = (byte)(n & 0xff);
            b[6] = (byte)(n >> 8 & 0xff);
            b[5] = (byte)(n >> 16 & 0xff);
            b[4] = (byte)(n >> 24 & 0xff);
            b[3] = (byte)(n >> 32 & 0xff);
            b[2] = (byte)(n >> 40 & 0xff);
            b[1] = (byte)(n >> 48 & 0xff);
            b[0] = (byte)(n >> 56 & 0xff);
            return b;
        }

        /**
         * long类型转byte[] (小端)
         *
         * @param n
         * @return
         */
        public static byte[] longToB_lsb(long n)
        {
            byte[] b = new byte[8];
            b[0] = (byte)(n & 0xff);
            b[1] = (byte)(n >> 8 & 0xff);
            b[2] = (byte)(n >> 16 & 0xff);
            b[3] = (byte)(n >> 24 & 0xff);
            b[4] = (byte)(n >> 32 & 0xff);
            b[5] = (byte)(n >> 40 & 0xff);
            b[6] = (byte)(n >> 48 & 0xff);
            b[7] = (byte)(n >> 56 & 0xff);
            return b;
        }

        /**
         * byte[]转long类型(小端)
         *
         * @param array
         * @return
         */
        public static long bToLong_lsb(byte[] array)
        {
            return ((((long)array[0] & 0xff) << 0)
                    | (((long)array[1] & 0xff) << 8)
                    | (((long)array[2] & 0xff) << 16)
                    | (((long)array[3] & 0xff) << 24)
                    | (((long)array[4] & 0xff) << 32)
                    | (((long)array[5] & 0xff) << 40)
                    | (((long)array[6] & 0xff) << 48)
                    | (((long)array[7] & 0xff) << 56));
        }

        /**
         * byte[]转long类型(大端)
         *
         * @param array
         * @return
         */
        public static long bToLong_msb(byte[] array)
        {
            return ((((long)array[0] & 0xff) << 56)
                    | (((long)array[1] & 0xff) << 48)
                    | (((long)array[2] & 0xff) << 40)
                    | (((long)array[3] & 0xff) << 32)
                    | (((long)array[4] & 0xff) << 24)
                    | (((long)array[5] & 0xff) << 16)
                    | (((long)array[6] & 0xff) << 8)
                    | (((long)array[7] & 0xff) << 0));
        }

        /**
         * 获取 64位以下 无符号 整数 （大端）
         *
         * @param byteBuf
         * @param readerIndex 开始位置
         * @param length      长度 8以下
         * @return
         */
        public static long bToU64msb(byte[] byteBuf, int readerIndex, int length)
        {
            long temp;
            temp = byteBuf[readerIndex] & 0x00ff;
            if (length > 1)
            {
                for (int i = 1; i < length; i++)
                {
                    temp = (temp << 8 | (byteBuf[readerIndex + i] & 0x00ff));
                }
            }
            return temp;
        }


        /**
         * 获取 64位以下 无符号 整数 （小端）
         *
         * @param byteBuf
         * @param readerIndex 开始位置
         * @param length      长度 8以下
         * @return
         */
        public static long bToU64lsb(byte[] byteBuf, int readerIndex, int length)
        {
            long temp;
            temp = byteBuf[readerIndex + length - 1] & 0x00ff;
            if (length > 1)
            {
                for (int i = length - 2; i >= 0; i--)
                {
                    temp = (temp << 8 | (byteBuf[readerIndex + i] & 0x00ff));
                }
            }
            return temp;
        }

        /**
         * 获取 64位以下 有符号 整数 （大端）
         *
         * @param byteBuf
         * @param readerIndex 开始位置
         * @param length      长度 8以下
         * @return
         */
        public static long bToInt64msb(byte[] byteBuf, int readerIndex, int length)
        {
            long temp;
            temp = byteBuf[readerIndex];
            if (length > 1)
            {
                for (int i = 1; i < length; i++)
                {
                    temp = (temp << 8 | (byteBuf[readerIndex + i] & 0x00ff));
                }
            }
            return temp;
        }

        /**
         * 获取 64位以下 有符号 整数 （小端）
         *
         * @param byteBuf
         * @param readerIndex 开始位置
         * @param length      长度 8以下
         * @return
         */
        public static long bToInt64lsb(byte[] byteBuf, int readerIndex, int length)
        {
            long temp;
            temp = byteBuf[readerIndex + length - 1];
            if (length > 1)
            {
                for (int i = length - 2; i >= 0; i--)
                {
                    temp = (temp << 8 | (byteBuf[readerIndex + i] & 0x00ff));
                }
            }
            return temp;
        }


        //endregion

        //region ------------------浮点--------------------------------------


        /**
         * 32位浮点 转字节 大端
         *
         * @param buf
         * @param value
         * @param writeIndex
         */
        public static void floatToB_msb(byte[] buf, float value, int writeIndex)
        {

            byte[] b = BitConverter.GetBytes(value);
            Array.Reverse(b); //需要先反转顺序，转大端的
            Array.Copy(b, 0, buf, writeIndex, 4);
        }

        /**
         * 32位浮点 转字节 小端
         *
         * @param buf
         * @param value
         * @param writeIndex
         */
        public static void floatToB_lsb(byte[] buf, float value, int writeIndex)
        {
            byte[] b = BitConverter.GetBytes(value);
            Array.Copy(b, 0, buf, writeIndex, 4);
        }

        /**
         * 64位浮点 转字节 大端
         *
         * @param buf
         * @param value
         * @param writeIndex
         */
        public static void doubleToB_msb(byte[] buf, double value, int writeIndex)
        {
            byte[] b = BitConverter.GetBytes(value);
            Array.Reverse(b); //需要先反转顺序，转大端的
            Array.Copy(b, 0, buf, writeIndex, 8);
        }

        /**
         * 64位浮点 转字节 小端
         *
         * @param buf
         * @param value
         * @param writeIndex
         */
        public static void doubleToB_lsb(byte[] buf, double value, int writeIndex)
        {
            byte[] b = BitConverter.GetBytes(value);
            Array.Copy(b, 0, buf, writeIndex, 8);
        }

        /**
         * 获取 32位  浮点 大端
         *
         * @param byteBuf
         * @param readerIndex 开始位置
         * @return
         */
        public static float bToFloat_msb(byte[] byteBuf, int readerIndex)
        {
            byte[] data = new byte[] { byteBuf[readerIndex + 3], byteBuf[readerIndex + 2], byteBuf[readerIndex + 1], byteBuf[readerIndex] };
            return BitConverter.ToSingle(data, readerIndex);
        }

        /**
         * 获取 32位  浮点 小端
         *
         * @param byteBuf
         * @param readerIndex 开始位置
         * @return
         */
        public static float bToFloat_lsb(byte[] byteBuf, int readerIndex)
        {
            return BitConverter.ToSingle(byteBuf, 0);
        }

        /**
         * 获取 64位以下  浮点 大端
         *
         * @param byteBuf
         * @param readerIndex
         * @return
         */
        public static double bToDouble_msb(byte[] byteBuf, int readerIndex)
        {
            Array.Reverse(byteBuf, readerIndex, 8); //需要先反转顺序，因为本地转换函数是小端的
            double res = BitConverter.ToDouble(byteBuf, readerIndex);
            Array.Reverse(byteBuf, readerIndex, 8); //用完，再反转回来，避免破坏数据
            return res;
        }

        /**
         * 获取 64位以下  浮点 小端
         *
         * @param byteBuf
         * @param readerIndex
         * @return
         */
        public static double bToDouble_lsb(byte[] byteBuf, int readerIndex)
        {
            return BitConverter.ToDouble(byteBuf, readerIndex);

        }
        //endregion

        //endregion




        public static UInt16 BuildU16(byte[] data, int offset)
        {
            UInt16 temp;
            temp = data[offset + 1];
            temp <<= 8;
            temp |= data[offset];
            return temp;
        }
        public static UInt32 BuildU32(byte[] data, int offset)
        {
            UInt32 temp;
            temp = data[offset + 3];
            temp <<= 8;
            temp = data[offset + 2];
            temp <<= 8;
            temp = data[offset + 1];
            temp <<= 8;
            temp |= data[offset];
            return temp;
        }
        public static UInt64 BuildU64(byte[] data, int offset)
        {
            UInt32 temp;
            temp = data[offset + 7];
            temp <<= 8;
            temp = data[offset + 6];
            temp <<= 8;
            temp = data[offset + 5];
            temp <<= 8;
            temp = data[offset + 4];
            temp <<= 8;
            temp = data[offset + 3];
            temp <<= 8;
            temp = data[offset + 2];
            temp <<= 8;
            temp = data[offset + 1];
            temp <<= 8;
            temp |= data[offset];
            return temp;
        }
        public static void BuildBytesU16(byte[] data, int offset, UInt16 val)
        {
            data[offset + 1] = (byte)(val >> 8);
            data[offset] = (byte)val;
        }
        public static void BuildBytesU32(byte[] data, int offset, UInt32 val)
        {
            data[offset + 3] = (byte)(val >> 24);
            data[offset + 2] = (byte)(val >> 16);
            data[offset + 1] = (byte)(val >> 8);
            data[offset] = (byte)val;
        }
        public static void BuildBytesU64(byte[] data, int offset, UInt64 val)
        {
            data[offset + 7] = (byte)(val >> 56);
            data[offset + 6] = (byte)(val >> 48);
            data[offset + 5] = (byte)(val >> 40);
            data[offset + 4] = (byte)(val >> 32);
            data[offset + 3] = (byte)(val >> 24);
            data[offset + 2] = (byte)(val >> 16);
            data[offset + 1] = (byte)(val >> 8);
            data[offset] = (byte)val;
        }
        public static byte[] CloneBytes(byte[] data, int offset, int len)
        {
            byte[] buf = new byte[len];
            Array.Copy(data, offset, buf, 0, len);
            return buf;

        }
        public static bool IsAddrEquals(byte[] addr0, byte[] addr1)
        {
            if (addr0.Length != addr1.Length)
                return false;
            for (int i = 0; i < addr1.Length; i++)
            {
                if (addr0[i] != addr1[i])
                    return false;
            }
            return true;
        }
        public static string AddrToString(byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    returnStr += bytes[i].ToString("X2");
                }
            }
            return returnStr;
        }
        public static UInt64 GetTimeStamp()
        {
            TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            UInt64 tmp = (UInt64)ts.TotalMilliseconds;
            return (tmp / 10000000);
        }

        public static void SaveSystemConfigFile(string config)
        {
            string path = Directory.GetCurrentDirectory();
            path += "/System.cfg";
            SaveTxtFile(path, config);
        }

        public static void SaveDeviceConfigFile(string config)
        {
            string path = Directory.GetCurrentDirectory();
            path += "/device.cfg";
            SaveTxtFile(path, config);
        }


        public static void SaveTxtFile(string path, String txt)
        {

            if (File.Exists(path))
            {
                File.Delete(path);
            }
            StreamWriter sw = File.CreateText(path);
            sw.Write(txt);
            sw.Flush();
            sw.Close();
        }



        public static byte[] ReadFile(string path)
        {
            FileStream fs = File.OpenRead(path);
            byte[] buf = new byte[fs.Length];
            int slen = fs.Read(buf, 0, buf.Length);
            fs.Close();
            if (slen > 0)
            {
                return buf;
            }
            return null;
        }
    }
}
